/*
 * @Description:
 * @FilePath: /stm32f1_library/USER/bsp/uart.h
 * @Author: Wei Zhou
 * @Github: https://github.com/zromyk
 * @Date: 2021-04-28 15:25:19
 * @LastEditors: Wei Zhou
 * @LastEditTime: 2021-09-05 13:14:03
 * @Copyright: Copyright ? 2017 muyiro. All rights reserved.
 */

#ifndef USART_INIT_H
#define USART_INIT_H

#include "my_include.h"
#include "dma.h"
#include "gpio.h"
#include <stdio.h>

typedef struct
{
    USART_TypeDef   * const USARTx;
    uint32_t        const RCC_Periph_USART;
    PIN_Dev         const pin_rx;
    PIN_Dev         const pin_tx;

    uint8_t         * const tx_buf;
    uint8_t         * const rx_buf;
    uint32_t        const tx_buf_size;
    uint32_t        const rx_buf_size;
    uint32_t        rx_cnt;

    IRQn_Type       const USARtx_IRQn;

    DMA_Dev         dma;
} USART_Dev;

#define DEBUG_USART              USART3

#define TxBuffer_Size_USART1     32
#define RxBuffer_Size_USART1     32

#define TxBuffer_Size_USART2     32
#define RxBuffer_Size_USART2     32

#define TxBuffer_Size_USART3     32
#define RxBuffer_Size_USART3     32

extern uint8_t TxBuffer_USART1[TxBuffer_Size_USART1];
extern uint8_t RxBuffer_USART1[RxBuffer_Size_USART1];

extern uint8_t TxBuffer_USART2[TxBuffer_Size_USART2];
extern uint8_t RxBuffer_USART2[RxBuffer_Size_USART2];

extern uint8_t TxBuffer_USART3[TxBuffer_Size_USART3];
extern uint8_t RxBuffer_USART3[RxBuffer_Size_USART3];

extern USART_Dev usart1;
extern USART_Dev usart2;
extern USART_Dev usart3;

/*
 This is an example of using a USART device.

    usart_init(&usart1, 115200, 0, 0);
    usart_dma_rx_init(&usart1);
    usart_dma_tx_init(&usart1, 0, 1);
    usart_dma_tx_size_enable(&usart1, // size of buffer //);
    //// or use:
    // usart_dma_tx_enable(&usart1); // Send size of usart1 buffer.
*/

/**
 * @brief: USART initialize.
 * @param  *usart:      point to a USART_Dev.
 * @param  baudRate:    串口波特率
 * @param  priority:    主优先级
 * @param  subPriority: 子优先级
 * @eg.    usart_init(&usart1, 115200, 0, 0);
 */
void usart_init(USART_Dev *usart, uint32_t baudRate, uint8_t priority, uint8_t subPriority);

/**
 * @brief: USART initialize.
 * @param  *usart:          point to a USART_Dev.
 * @param  *init_struct:    point to a USART_InitTypeDef.
 * @param  priority:        主优先级
 * @param  subPriority:     子优先级
 * @eg.    usart_init(&usart1, 115200, 0, 0);
 */
void usart_user_define_init_init(USART_Dev *usart, USART_InitTypeDef *init_struct, uint8_t priority, uint8_t subPriority);

/* usart dma functions ------------------------------------------------------- */
/**
 * @brief  初始化 DMA 接收，包含 DMA 接收中断.
   注意：在初始化 DMA 之前，需要先初始化 USART (usart_init)
 * @param  *usart:      point to a USART_Dev.
 * @retval None
 */
void usart_dma_rx_init(USART_Dev *usart);

/**
 * @brief  初始化 DMA 发送
   注意：在初始化 DMA 之前，需要先初始化 USART (usart_init)
 * @param  *usart:      point to a USART_Dev.
 * @param  priority:    主优先级
 * @param  subPriority: 子优先级
 * @retval None
 */
void usart_dma_tx_init(USART_Dev *usart, uint8_t priority, uint8_t subPriority);

/**
 * @brief  使能 DMA 发送
 * @param  *usart:  point to a USART_Dev.
 * @param  size:    发送缓冲区内的 size 个字节数据
 * @retval None
 */
void usart_dma_tx_size_enable(USART_Dev *usart, uint32_t size);

/**
 * @brief  使能 DMA 发送，发送缓冲区内的所有数据
 * @param  *usart:  point to a USART_Dev.
 * @retval None
 */
void usart_dma_tx_enable(USART_Dev *usart);

/* Send information functions ------------------------------------------------------- */
/**
 * @brief  write 1 byte.
 * @param  *usart:  point to a USART_Dev.
 * @param  *byte:   a byte information.
 * @retval None
 */
void usart_write_byte(USART_Dev *usart, const uint8_t byte);

/**
 * @brief  write buffer.
 * @param  *usart:  point to a USART_Dev.
 * @param  *buf:    point to a buffer where your data save.
 * @param  length:  the length of buffer.
 * @retval None
 */
void usart_write_buffer(USART_Dev *usart, const uint8_t *buf, uint32_t length);

/**
 * @brief  write string.
 * @param  *usart:  point to a USART_Dev.
 * @param  *str:    point to a string (end with '\0')
 * @retval None
 */
void usart_write_string(USART_Dev *usart, const uint8_t *str);

/**
 * @brief  串口转发，将 buf 内的 length 个字节数据转发到 debug usart.
 * @param  *buf:    point to a buffer where your data save.
 * @param  length:  the length of buffer.
 * @retval None
 */
void usart_reply(const uint8_t *buf, uint32_t length);

#endif /* USART_INIT_H */
